package org.hackystat.ambientdevice.device.orb;

import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.Test;
import org.hackystat.ambientdevice.ConfigurationException;
import org.hackystat.ambientdevice.device.orb.AmbientOrb.Animation;
import org.hackystat.ambientdevice.device.orb.AmbientOrb.Color;
import org.hackystat.ambientdevice.server.jaxb.Action;

/**
 * Test case for AmbientOrb.
 * 
 * @author Shaoxuan Zhang
 */
public class TestAmbientOrb {

  private static final String testId01 = "123-456-789";
  private static final String testId02 = "ABC-DEF-GHI";

  /**
   * Test GetOrb. Make sure that orbs with the same device ID are the same instance.
   */
  @Test
  public void testGetOrb() {
    AmbientOrb testOrb01 = AmbientOrb.getOrb(testId01);
    AmbientOrb testOrb02 = AmbientOrb.getOrb(testId02);
    AmbientOrb testOrb03 = AmbientOrb.getOrb(testId01);
    assertSame("two orb with the same deviceId should be the same object", testOrb01, testOrb03);
    assertNotSame("two orb with the different deviceId should be different objects", testOrb01,
        testOrb02);
  }

  /**
   * Test the getUrl. Make sure that correct information is included in the request.
   */
  @Test
  public void testGetUrl() {
    AmbientOrb testOrb01 = AmbientOrb.getOrb(testId01);
    testOrb01.setAnim(Animation.HEARTBEAT);
    testOrb01.setColor(Color.RED);
    testOrb01.setComment("AmbientOrb Test Case.");
    String url = testOrb01.getUrl();
    assertTrue("Server address should in the URL.", url.contains(AmbientOrb.SERVER));
    assertTrue("Correct device ID should in the URL.", url.contains("devID=" + testId01));
    assertTrue("Correct color number should in the URL.", url.contains("color=0"));
    assertTrue("Correct animation number should in the URL.", url.contains("anim=9"));
    assertTrue("Correct comment should in the URL.", url.contains("comment=AmbientOrb Test Case."));
  }
  
  /**
   * Test getAction.
   * @throws ConfigurationException for some errors
   */
  @Test
  public void testGetAction() throws ConfigurationException {
    AmbientOrb testOrb01 = AmbientOrb.getOrb(testId01);
    Action action = new Action();
    //with null value
    try {
      action.setActionType("ChangePulse");
      testOrb01.getAction(action);
      fail("Exception is expected.");
    }
    catch (ConfigurationException e) {
      assertTrue("Check message", e.getMessage().contains("cannot be null"));
    }
    //with invalid action type
    try {
      action.setValue("BLACK");
      testOrb01.getAction(action);
      fail("Exception is expected.");
    }
    catch (ConfigurationException e) {
      assertTrue("Check message", e.getMessage().contains("ChangePulse is not supported"));
    }
    //with invalid value
    try {
      action.setActionType("ChangeColor");
      testOrb01.getAction(action);
      fail("Exception is expected.");
    }
    catch (ConfigurationException e) {
      assertTrue("Check message", e.getMessage().contains("BLACK is not supported"));
    }
    //everything is right
    action.setValue("RED");
    assertTrue("Check the real Class of the action",
        testOrb01.getAction(action) instanceof ChangeColor);
  }
}
